package com.wjpeng.wms.service.impl;

import com.alibaba.druid.sql.visitor.functions.Insert;
import com.wjpeng.wms.domain.*;
import com.wjpeng.wms.mapper.*;
import com.wjpeng.wms.query.StockOutcomeBillQueryObject;
import com.wjpeng.wms.service.IStockOutcomeBillService;
import com.wjpeng.wms.util.PageResult;
import com.wjpeng.wms.util.UserContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@Service
public class StockOutcomeBillServiceImpl implements IStockOutcomeBillService {
    @Autowired
    private StockOutcomeBillMapper billMapper;

    @Autowired
    private StockOutcomeBillItemMapper itemMapper;

    @Autowired
    private ProductStockMapper productStockMapper;

    @Autowired
    private SaleAccountMapper saleAccountMapper;

    @Override
    public void saveOrUpdate(StockOutcomeBill d) {
        if(d.getId() == null){
            saveBill(d);
        }else{
            updateBill(d);
        }


    }

    //保存订单
    private void saveBill(StockOutcomeBill entity){
        //1:设置录入人
        entity.setInputUser(UserContext.getCurrentUser());
        //2:设置录入时间
        entity.setInputTime(new Date());
        //3:设置单据状态
        entity.setStatus(StockOutcomeBill.NORMAL);
        //4:定义两个变量,来记录当前单据的总数量和总金额
        BigDecimal totalNumber = BigDecimal.ZERO;
        BigDecimal totalAmount = BigDecimal.ZERO;
        //5:设置明细数据
        for (StockOutcomeBillItem item : entity.getItems()) {
            //4.1:计算单据的小计
            BigDecimal amount = item.getNumber().multiply(item.getSalePrice())
                .setScale(2, RoundingMode.HALF_UP);
            item.setAmount(amount);
            //4.2:叠加总数量和总计
            totalAmount = totalAmount.add(amount);
            totalNumber = totalNumber.add(item.getNumber());
        }
        //6:设置单据的总价和总数量
        entity.setTotalAmount(totalAmount);
        entity.setTotalNumber(totalNumber);
        //7:保存单据到数据库中
        billMapper.insert(entity);
        for (StockOutcomeBillItem item : entity.getItems()) {
            item.setBillId(entity.getId());
            itemMapper.insert(item);
        }
    }



    //更新单据
    private void updateBill(StockOutcomeBill entity) {
        //根据单据的ID查询完整的单据信息
        StockOutcomeBill bill = billMapper.selectByPrimaryKey(entity.getId());
        //检验当前单据的状态,未审核才能更新
        if(bill.getStatus() == StockOutcomeBill.NORMAL){
            //核心,重新计算明细小计,单据的总数量和总价格
            //1:删除当前单据所有的明细
            itemMapper.deleteItemByBillId(bill.getId());
            //2:定义变量来记录总数和总价
            BigDecimal totalNumber = BigDecimal.ZERO;
            BigDecimal totalAmount = BigDecimal.ZERO;
            //3:计算单据的总价和总数量
            for (StockOutcomeBillItem item : entity.getItems()) {
                //3.1:保存明细的总价
                BigDecimal amount = item.getNumber().multiply(item.getSalePrice())
                        .setScale(2, RoundingMode.HALF_UP);
                item.setAmount(amount);
                //3.2叠加总数量和总金额
                totalAmount = totalAmount.add(amount);
                totalNumber = totalNumber.add(item.getNumber());
                //4:保存明细
                item.setBillId(entity.getId());
                itemMapper.insert(item);
            }
            //回填传递的订单数据
            entity.setTotalNumber(totalNumber);
            entity.setTotalAmount(totalAmount);
            //5:更新订单
            billMapper.updateByPrimaryKey(entity);
        }

    }

    @Override
    public void delete(Long id) {
        //根据单据的ID查询完整的单据信息
        StockOutcomeBill old = billMapper.selectByPrimaryKey(id);
        //检验当前单据的状态,未审核才能更新
        if(old.getStatus() == StockOutcomeBill.NORMAL){
            //删除当前单据的明细,在删除订单
            itemMapper.deleteItemByBillId(id);
            billMapper.deleteByPrimaryKey(id);

        }


    }

    @Override
    public StockOutcomeBill get(Long id) {
        return billMapper.selectByPrimaryKey(id);
    }


    @Override
    public PageResult result(StockOutcomeBillQueryObject qo) {
        Integer count = billMapper.queryCount(qo);
        if(count == 0){
            return new PageResult(Collections.EMPTY_LIST,0,1,0);
        }
        return new PageResult(billMapper.queryLimit(qo),count,qo.getCurrentPage(),qo.getPageSize());
    }

    @Override
    public void audit(Long id) {
        //根据单据的ID查询完整的单据信息
        StockOutcomeBill bill = billMapper.selectByPrimaryKey(id);
        //检验当前单据的状态,未审核的才能审核
        if (bill.getStatus() == StockOutcomeBill.NORMAL) {
            //获取当前入库的仓库
            Depot depot = bill.getDepot();
            //1:迭代当前单据中所有的明细,依次出库
            for (StockOutcomeBillItem item : bill.getItems()) {
                //获取当前明细的商品档案
                Product product = item.getProduct();

                //===============出库操作==================
                //1.1:查询该仓库中是否有该商品
                ProductStock productStock = productStockMapper
                .selectByProductAndDepot(product.getId(), depot.getId());
                //1.2:该商品在该仓库中没有库存,抛出一个异常
                if (productStock == null) {
                    String msg = "仓库["+depot.getName()+"]没有该商品["+product.getName()+"]的库存";
                    throw new RuntimeException(msg);
                }
                //1.3:检查库存数量是否满足出库的数量
                if(item.getNumber().compareTo(productStock.getStoreNumber()) > 0){
                    String msg= "仓库"+product.getName()+"商品库存"+productStock.getStoreNumber()+
                            "不足出库数量:"+item.getNumber();
                    throw new RuntimeException(msg);
                }
                //1.4:满足出库要求,减少总价值,减少总数量
                BigDecimal amount = item.getNumber().multiply(item.getSalePrice())
                        .setScale(2, RoundingMode.HALF_UP);
                BigDecimal am = amount;
                amount = productStock.getAmount().subtract(amount);
                productStock.setAmount(amount);//设置当前商品库存的总价值
                BigDecimal number = productStock.getStoreNumber().subtract(item.getNumber());
                productStock.setStoreNumber(number);
                //1.5:更新库存
                productStockMapper.updateByPrimaryKey(productStock);

                //=================记账操作====================
                SaleAccount saleAccount = new SaleAccount();
                saleAccount.setVdate(new Date());
                saleAccount.setNumber(item.getNumber());
                saleAccount.setCostPrice(product.getCostPrice());
                saleAccount.setCostAmount(item.getProduct().getCostPrice().multiply(item.getNumber())
                        .setScale(2,RoundingMode.HALF_UP));
                saleAccount.setSalePrice(item.getSalePrice());
                saleAccount.setSaleAmount(am);
                saleAccount.setProduct(product);
                saleAccount.setSaleman(bill.getInputUser());
                saleAccount.setClient(bill.getClient());
                saleAccountMapper.insert(saleAccount);
            }

            //设置单据的审核人,时间,状态
            bill.setAuditTime(new Date());
            bill.setAuditor(UserContext.getCurrentUser());
            bill.setStatus(StockOutcomeBill.AUDIT);
            billMapper.audit(bill);
        }
    }
}
